<template>
  <PageWrapper contentFullHeight title="账户安全">
    <template #rightFooter>
      <a-button
        type="primary"
        @click="onSubmit"
        :loading="submitLoading"
        v-auth="'AccountConfigPriv.Save'"
      >
        确认
      </a-button>
    </template>

    <a-form
      ref="formRef"
      :model="formState"
      :label-col="labelCol"
      :wrapper-col="wrapperCol"
      labelAlign="left"
    >
      <a-card title="账户安全配置" class="w-full" style="margin-bottom: 24px" :canExpan="false">
        <a-skeleton :loading="skeletonLoading" active>
          <a-form-item label="否启用账户安全配置" name="isOpenThreeSecurity">
            <a-switch
              v-model:checked="formState.isOpenThreeSecurity"
              @change="openThreeSecurityChange"
            />
          </a-form-item>
        </a-skeleton>
      </a-card>
      <div v-show="formState.isOpenThreeSecurity">
        <a-card title="密码规则配置" class="w-full" style="margin-bottom: 24px" :canExpan="false">
          <a-form-item label="密码最小长度" name="passwordMinLength">
            <a-input-number v-model:value="formState.passwordMinLength" :min="6" :max="50" />
          </a-form-item>
          <a-form-item label="密码最大长度" name="passwordMaxLength">
            <a-input-number v-model:value="formState.passwordMaxLength" :min="6" :max="50" />
          </a-form-item>
          <a-form-item label="密码字符要求" name="passwordCharacterSpecification">
            <a-select v-model:value="formState.passwordCharacterSpecification">
              <a-select-option value="A">无要求</a-select-option>
              <a-select-option value="B">必须同时包含字母和数字</a-select-option>
              <a-select-option value="C">必须同时包含大写字母、小写字母、数字</a-select-option>
              <a-select-option value="D">必须同时包含大、小写字母、特殊字符、数字</a-select-option>
            </a-select>
          </a-form-item>
          <a-form-item label="密码中不能包含的用户信息" name="notIncludeUserInfo">
            <a-checkbox-group v-model:value="formState.notIncludeUserInfo">
              <a-checkbox value="UserName" name="notIncludeUserInfo">用户名</a-checkbox>
              <a-checkbox value="RealName" name="notIncludeUserInfo">用户真实姓名</a-checkbox>
              <a-checkbox value="Email" name="notIncludeUserInfo">电子邮箱</a-checkbox>
              <a-checkbox value="Mobile" name="notIncludeUserInfo">手机号</a-checkbox>
            </a-checkbox-group>
          </a-form-item>
        </a-card>

        <a-card title="密码校检配置" class="w-full" style="margin-bottom: 24px" :canExpan="false">
          <a-form-item
            label="一天内密码错误次数超过最大重试次数锁定账号"
            name="specifyOverTimeLock"
          >
            <a-switch
              v-model:checked="formState.specifyOverTimeLock"
              @change="specifyOverTimeLockChange"
            />
          </a-form-item>
          <a-form-item
            label="密码错误最大重试次数"
            name="maxLoginCount"
            extra="注：登录密码最大校检次数不设置或设置为0则不进行校验"
          >
            <a-input-number
              v-model:value="formState.maxLoginCount"
              :disabled="!formState.specifyOverTimeLock"
            />
          </a-form-item>
          <a-form-item label="超过密码错误最大重试次数处理方式" name="overLoginCountType">
            <a-select
              v-model:value="formState.overLoginCountType"
              @change="overLoginCountTypeChange"
            >
              <a-select-option value="">不处理</a-select-option>
              <a-select-option value="A">锁定账号</a-select-option>
              <a-select-option value="B">指定时间内禁止登录</a-select-option>
            </a-select>
          </a-form-item>
          <a-form-item
            label="禁止登录时长"
            name="lockTime"
            extra="注：账户锁定时间设置为0或为空时则不锁定，最长锁定时间为100天"
          >
            <a-input-number
              v-model:value="formState.lockTime"
              :min="0"
              :max="100"
              :disabled="formState.overLoginCountType != 'B'"
            />
          </a-form-item>
        </a-card>

        <a-card title="密码变更通知" class="w-full" style="margin-bottom: 24px" :canExpan="false">
          <a-form-item
            label="指定密码过期时间"
            name="expiration"
            extra="注：指定密码时间设置为0或空时将不过期"
          >
            <a-input-number
              v-model:value="formState.expiration"
              :disabled="!formState.specifyOverTimeLock"
            />
          </a-form-item>
          <a-form-item label="后台重置密码后下次登录是否强制修改密码" name="nextLoginUpdatePwd">
            <a-switch v-model:checked="formState.nextLoginUpdatePwd" />
          </a-form-item>
        </a-card>
      </div>
    </a-form>
  </PageWrapper>
</template>
<script lang="ts">
  import { ValidateErrorEntity } from 'ant-design-vue/es/form/interface';
  import { defineComponent, reactive, ref, toRaw, UnwrapRef } from 'vue';
  import { PageWrapper } from '/@/components/Page';
  import { getSecurity, saveSecurity } from '/@/api/system/system';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { Card, Form, Skeleton, Switch, InputNumber, Select, Checkbox } from 'ant-design-vue';
  interface FormState {
    isOpenThreeSecurity: boolean;
    passwordMinLength: Number;
    passwordMaxLength: Number;
    passwordCharacterSpecification: string;
    notIncludeUserInfo: string[];
    specifyOverTimeLock: boolean;
    maxLoginCount: Number;
    overLoginCountType: string;
    lockTime: Number;
    expiration: Number;
    nextLoginUpdatePwd: boolean;
  }

  export default defineComponent({
    name: 'Security',
    components: {
      PageWrapper,
      [Card.name]: Card,
      [Form.name]: Form,
      AFormItem: Form.Item,
      [Skeleton.name]: Skeleton,
      [Switch.name]: Switch,
      [InputNumber.name]: InputNumber,
      ASelectOption: Select.Option,
      [Select.name]: Select,
      [Checkbox.name]: Checkbox,
      ACheckboxGroup: Checkbox.Group,
    },
    setup() {
      const { createMessage } = useMessage();
      const formRef = ref();
      let submitLoading = ref(false);
      let skeletonLoading = ref(false);
      const formState: UnwrapRef<FormState> = reactive({
        isOpenThreeSecurity: false,
        passwordMinLength: 6,
        passwordMaxLength: 30,
        passwordCharacterSpecification: 'A',
        notIncludeUserInfo: [],
        specifyOverTimeLock: false,
        maxLoginCount: 6,
        overLoginCountType: '',
        lockTime: 0,
        expiration: 0,
        nextLoginUpdatePwd: false,
      });

      skeletonLoading.value = true;
      getSecurity().then((res) => {
        formState.isOpenThreeSecurity = res.isOpenThreeSecurity;
        formState.passwordMinLength = parseInt(res.passwordMinLength);
        formState.passwordMaxLength = parseInt(res.passwordMaxLength);
        formState.passwordCharacterSpecification = res.passwordCharacterSpecification;
        formState.notIncludeUserInfo = res.notIncludeUserInfo;
        formState.specifyOverTimeLock = res.specifyOverTimeLock;
        formState.maxLoginCount = parseInt(res.maxLoginCount);
        formState.overLoginCountType = res.overLoginCountType;
        formState.lockTime = parseInt(res.lockTime);
        formState.expiration = parseInt(res.expiration);
        formState.nextLoginUpdatePwd = res.nextLoginUpdatePwd;
        skeletonLoading.value = false;
      });

      const openThreeSecurityChange = (ischeck) => {
        formState.isOpenThreeSecurity = ischeck;
      };

      const specifyOverTimeLockChange = (ischeck) => {
        formState.specifyOverTimeLock = ischeck;
      };

      const overLoginCountTypeChange = (val) => {
        formState.overLoginCountType = val;
      };

      const onSubmit = () => {
        formRef.value
          .validate()
          .then(() => {
            console.log('values', formState, toRaw(formState));
            submitLoading.value = true;
            saveSecurity(toRaw(formState)).then(() => {
              createMessage.success('保存成功');
              submitLoading.value = false;
            });
          })
          .catch((error: ValidateErrorEntity<FormState>) => {
            console.log('error', error);
          });
      };
      return {
        formRef,
        labelCol: { span: 8 },
        wrapperCol: { span: 8 },
        other: '',
        formState,
        submitLoading,
        skeletonLoading,
        openThreeSecurityChange,
        specifyOverTimeLockChange,
        overLoginCountTypeChange,
        onSubmit,
      };
    },
  });
</script>
